package com.airS.task.fileMgr.utils.file;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.ExternalOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.ConnectException;

/**
 * Created by alan on 2017/3/16.
 */
public class FileUtils {

    private static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    /**
     * 复制单个文件(可更名复制)
     *
     * @param oldPFile 准备复制的文件源
     * @param newFile  拷贝到新绝对路径带文件名(注：目录路径需带文件名)
     * @return
     */
    public static boolean copySingleFile(File oldPFile, File newFile) {
        InputStream inStream = null;
        FileOutputStream fs = null;
        try {
            int bytesum = 0;
            int byteread = 0;
            if (oldPFile.exists()) { //文件存在时
                inStream = new FileInputStream(oldPFile); //读入原文件
                fs = new FileOutputStream(newFile);
                byte[] buffer = new byte[1444];
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
                oldPFile.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                fs.flush();
                fs.close();
                inStream.close();
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    /**
     * 文件转byte数组
     *
     * @param file
     * @return
     */
    public static byte[] fileToByteArray(File file) {
        byte[] buffer = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * 利用SWFTools工具将pdf转换成swf，转换完后的swf文件与pdf同名
     *
     * @authoriori
     * @paramfileDirPDF文件存放路径（包括文件名）
     * @paramexePath转换器安装路径
     * @throwsIOException
     */
    public static void pdf2swf(String fileDir, String exePath)
            throws IOException {
        // 文件路径
        String filePath = fileDir.substring(0, fileDir.lastIndexOf(File.separator));
        // 文件名，不带后缀
        String fileName = fileDir.substring((filePath.length() + 1),
                fileDir.lastIndexOf("."));
        Process pro = null;
        if (isWindowsSystem()) {
            // 如果是windows系统
            // 命令行命令
//            String cmd = exePath + " -s flashversion=9 -s poly2bitmap -T 9" + " \"" + fileDir + "\" -o \"" + filePath + "/"
//                    + fileName + ".swf\"";
            // -s flashversion=9
            //  -f -s poly2bitmap -s zoom=150
            String cmd = exePath + " -T 9 \"" + fileDir + "\" -o \"" + filePath + "/" + fileName + ".swf\"";
            // Runtime执行后返回创建的进程对象
            pro = Runtime.getRuntime().exec(cmd);
        } else {
            // 如果是linux系统,路径不能有空格，而且一定不能用双引号，否则无法创建进程
//            String[] cmd = new String[4];
//            cmd[0] = exePath;
//            cmd[1] = fileDir;
//            cmd[2] = filePath + "/" + fileName + ".swf";
//            // -f -s poly2bitmap -s zoom=150
//            cmd[3] = "-T 9";
            String cmd = cmd = exePath + " -T 9 " + fileDir + " -o " + filePath + "/" + fileName + ".swf";
            // Runtime执行后返回创建的进程对象
            pro = Runtime.getRuntime().exec(cmd);
        }
        // 非要读取一遍cmd的输出，要不不会flush生成文件（多线程）
        new DoOutput(pro.getInputStream()).start();
//        new DoOutput(pro.getErrorStream()).start();
        try {
            // 调用waitFor方法，是为了阻塞当前进程，直到cmd执行完
            pro.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断是否是windows操作系统
     *
     * @return
     * @authoriori
     */
    private static boolean isWindowsSystem() {
        String p = System.getProperty("os.name");
        return p.toLowerCase().indexOf("windows") >= 0 ? true : false;
    }

    /**
     * 多线程内部类 读取转换时cmd进程的标准输出流和错误输出流，这样做是因为如果不读取流，进程将死锁
     *
     * @authoriori
     */
    private static class DoOutput extends Thread {
        public InputStream is;

        // 构造方法
        public DoOutput(InputStream is) {
            this.is = is;
        }

        public void run() {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    this.is));
            String str = null;
            try {
                // 这里并没有对流的内容进行处理，只是读了一遍
                while ((str = br.readLine()) != null) {
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 将Office文档转换为PDF. 运行该函数需要用到OpenOffice, OpenOffice下载地址为
     * http://www.openoffice.org/
     * <p>
     * <pre>
     * 方法示例:
     * String sourcePath = "F:/office/source.doc";
     * String destFile = "F:/pdf/dest.pdf";
     * Converter.office2PDF(sourcePath, destFile);
     * </pre>
     *
     * @param sourceFile 源文件, 绝对路径. 可以是Office2003-2007全部格式的文档, Office2010的没测试. 包括.doc,
     *                   .docx, .xls, .xlsx, .ppt, .pptx等. 示例: F:/office/source.doc
     * @param destFile   目标文件. 绝对路径. 示例: F:/pdf/dest.pdf
     * @return 操作成功与否的提示信息. 如果返回 -1, 表示找不到源文件, 或url.properties配置错误; 如果返回 0,
     * 则表示操作成功; 返回1, 则表示转换失败
     */
    public static int openOffice2PDF(String openOfficeHome, String openOfficeHost, int openOfficePort, File sourceFile, File destFile) {
        OpenOfficeConnection connection = null;
        Process pro = null;
        try {
            if (!sourceFile.exists()) {
                return -1;// 找不到源文件, 则返回-1
            }

            // 启动OpenOffice的服务
//            String command = openOfficeHome
//                    + " -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard";
//            pro = Runtime.getRuntime().exec(command);
            // connect to an OpenOffice.org instance running on port 8100
            connection = new SocketOpenOfficeConnection(
                    openOfficeHost, openOfficePort);
            connection.connect();

            // convert
            DocumentConverter converter = new OpenOfficeDocumentConverter(
                    connection);
            converter.convert(sourceFile, destFile);
            return 0;
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//            return -1;
        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // close the connection
            if (connection != null)
                connection.disconnect();
            // 关闭OpenOffice服务的进程
            if (pro != null)
                pro.destroy();
        }

        return 1;
    }

    private static OfficeManager officeManager;

    public static boolean libreOffice2PDF(String libreOfficePath, int libreOfficePort, File sourceFile, File destFile) {
        try {
            ExternalOfficeManagerConfiguration externalProcessOfficeManager = new ExternalOfficeManagerConfiguration();
            externalProcessOfficeManager.setConnectOnStart(true);
            externalProcessOfficeManager.setPortNumber(libreOfficePort);
            officeManager = externalProcessOfficeManager.buildOfficeManager();
            officeManager.start();
            logger.info("已获取libreoffice连接");
        } catch (Exception ex) {
            DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
            configuration.setOfficeHome(libreOfficePath);
            configuration.setPortNumbers(libreOfficePort);
            configuration.setTaskExecutionTimeout(1000 * 60 * 5L);
            configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);
            officeManager = configuration.buildOfficeManager();
            officeManager.start();
            logger.warn("重新获取libreoffice连接");
        } finally {
            if (officeManager != null) {
                logger.info("libreoffice转换文件中：" + sourceFile);
                OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
                converter.convert(sourceFile, destFile);
                logger.info("libreoffice转换文件完成：" + sourceFile);
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 测试main方法
     *
     * @paramargs
     */
    public static void main(String[] args) {
        //,host=127.0.0.1,port=8100
//        FileUtils.office2PDF("C:\\Program Files (x86)\\OpenOffice 4\\program\\soffice.exe", "127.0.0.1" , 8100, "C:/Users/alan/Desktop/1234.docx", "C:/Users/alan/Desktop/1234.pdf");
//
//        // 转换器安装路径
//        String exePath = "D:/Program Files (x86)/SWFTools/pdf2swf.exe";
//        try {
//            FileUtils.pdf2swf("C:/Users/alan/Desktop/1234.pdf", exePath);
//        } catch (IOException e) {
//            System.err.println("转换出错！");
//            e.printStackTrace();
//        }

    }


}
